/***************************************************************************
 *   Copyright 2008 Fabrizio Angius <hippydream@gmail.com>                 *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Library General Public License as       *
 *   published by the Free Software Foundation; either version 2 of the    *
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this program; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
 ***************************************************************************/

// TODO: check for required parameters and handle missing callback
var Protoflickr = {
  Version: '0.1',

  ResponseType: 'json',
  RestUrl: '/proxy.php',
  ApiKey: '',
  ApiSignature: '',
  Secret: '',
  Frob: '',
  Request: null,
  ErrorHandler: null,

  load: function() {
    if((typeof Prototype=='undefined') || parseFloat(Prototype.Version.split(".")[0] + "." + Prototype.Version.split(".")[1]) < 1.4)
      throw("protoflickr requires the Prototype JavaScript framework >= 1.4.0");
  },

  init: function(apiKey, secret, errorHandler) {
    ApiKey = apiKey;
    Secret = secret ? secret : '';
    ApiSignature = secret && apiKey ? auth_generateSignature() : '';
    ErrorHandler = errorHandler ? errorHandler : null;

    Request = function(command, args, callback) {
      var url = Protoflickr.RestUrl;
      args['api_key'] = ApiKey;
      args['format'] = 'json';
      args['nojsoncallback'] = '1';
      args['method'] = command;

      new Ajax.Request(
        url,
          {
            method: 'post',
            parameters: args,
            evalJSON: true,
            onComplete: function (response) {
              if (response.readyState != 4) return;
              if (callback) callback(response.responseJSON);
            },
            onException: function (request, error) { if (ErrorHandler) ErrorHandler(request, error); else alert(error); }
          }
      );
    }
  },

  setErrorHandler : function(errorHandler) {
    ErrorHandler = errorHandler;
  },

  echo: function(callback) {
    Request('flickr.test.echo', {}, callback);
  },


  // TODO: authentication

  /*! \internal
  */
  auth_generateSignature: function() {
    if (!ApiKey || !Secret) return;
  },

  /*! Returns the URL to be used to authorize this application to use methods that
      require authentication.

     Arguments:
       perms
         One of 'read', 'write' or 'delete'
  */
  auth_authorizationUrl : function(perms) {
    if (!isString(perms) || (perms != 'read' && perms != 'write' && perms != 'delete'))
      perms = 'read';
    var url = 'http://flickr.com/services/auth/?';
    url += 'api_key=' + ApiKey;
    url += '&perms=' + perms;
    url += '&api_sig=' + ApiSignature;
    return url;
  },


  //////////////////////////////////////////////////////////////////////////
  // flickr API reference page: http://www.flickr.com/services/api/
  //////////////////////////////////////////////////////////////////////////


  //////////////////////////////////////////////////////////////////////////
  // Activity
  //////////////////////////////////////////////////////////////////////////

  /*! Returns a list of recent activity on photos commented on by the calling user.

      Reference: http://www.flickr.com/services/api/flickr.activity.userComments.html
      Authentication: read
      Note: Do not poll this method more than once an hour.
      TODO: Remember and check the last time the method has been called.

      Arguments:
        per_page (Optional)
          Number of items to return per page. If this argument is omitted, it defaults to 10. 
          The maximum allowed value is 50.
        page (Optional)
          The page of results to return. If this argument is omitted, it defaults to 1.
  */
  /*activity_userComments : function(callback, per_page, page) {
    var args = { };
    if (Object.isNumber(per_page) && per_page > 0 && per_page <= 50)
      args['per_page'] = per_page;
    if (Object.isNumber(page) && page > 0)
      args['page'] = page;
    Request('flickr.activity.userComments', args, callback);
  },*/

  /*! Returns a list of recent activity on photos belonging to the calling user.

      Reference: http://www.flickr.com/services/api/flickr.activity.userPhotos.html
      Authentication: read
      Note: Do not poll this method more than once an hour.
      TODO: Remember and check the last time the method has been called.

      Arguments:
        timeframe (Optional)
          The timeframe in which to return updates for. This can be specified in days ('2d') 
          or hours ('4h'). The default behavoir is to return changes since the beginning of 
          the previous user session.
        per_page (Optional)
          Number of items to return per page. If this argument is omitted, it defaults to 10. 
          The maximum allowed value is 50.
        page (Optional)
          The page of results to return. If this argument is omitted, it defaults to 1.
  */
  /*activity_userPhotos : function(callback, timeframe, per_page, page) {
    var args = { };
    if (isString(timeframe)) {
      var rx = /^[0-9]+[dh]$/;
      if (rx.test(timeframe))
        args['timeframe'] = timeframe;
    }
    if (Object.isNumber(per_page) && per_page > 0 && per_page <= 50)
      args['per_page'] = per_page;
    if (Object.isNumber(page) && page > 0)
      args['page'] = page;
    Request('flickr.activity.userPhotos', args, callback);
  },*/


  //////////////////////////////////////////////////////////////////////////
  // Auth
  //////////////////////////////////////////////////////////////////////////

  /*! Returns the credentials attached to an authentication token.
      This call must be signed as specified in the authentication API spec.

      Reference: http://www.flickr.com/services/api/flickr.auth.checkToken.html
      Authentication: none
      See also: http://www.flickr.com/services/api/auth.spec.html
  */
  /*auth_checkToken : function() {
  },*/


  //////////////////////////////////////////////////////////////////////////
  // Contacts
  //////////////////////////////////////////////////////////////////////////

  /*! Get the contact list for a user.

      Reference: http://www.flickr.com/services/api/flickr.contacts.getPublicList.html
      Authentication: none

      Arguments:
        user_id (Required)
          The NSID of the user to fetch information about.
        page (Optional)
          The page of results to return. If this argument is omitted, it defaults to 1.
        per_page (Optional)
          Number of photos to return per page. If this argument is omitted, it defaults to 1000. 
          The maximum allowed value is 1000.
  */
  contacts_getPublicList : function(callback, user_id, page, per_page) {
    var args = {'user_id':user_id};
    if (Object.isNumber(per_page) && per_page > 0 && per_page <= 1000)
      args['per_page'] = per_page;
    if (Object.isNumber(page) && page > 0)
      args['page'] = page;
    Request('flickr.contacts.getPublicList', args, callback);
  },


  //////////////////////////////////////////////////////////////////////////
  // Favorites
  //////////////////////////////////////////////////////////////////////////

  /*! Returns a list of favorite public photos for the given user.

      Reference: http://www.flickr.com/services/api/flickr.favorites.getPublicList.html
      Authentication: none

      Arguments:
        user_id (Required)
          The NSID of the user to fetch information about.
         extras (Optional)
          A comma-delimited list of extra information to fetch for each returned record. 
          Currently supported fields are: license, date_upload, date_taken, owner_name, icon_server, 
          original_format, last_update, geo, tags, machine_tags, o_dims, views, media.
        page (Optional)
          The page of results to return. If this argument is omitted, it defaults to 1.
        per_page (Optional)
          Number of photos to return per page. If this argument is omitted, it defaults to 100. 
          The maximum allowed value is 500.
  */
  favorites_getPublicList : function(callback, user_id, extras, page, per_page) {
    var args = {'user_id':user_id};
    if (Object.isNumber(per_page) && per_page > 0 && per_page <= 1000)
      args['per_page'] = per_page;
    if (Object.isNumber(page) && page > 0)
      args['page'] = page;
    if (Object.isString(extras))
      args['extras'] = extras;
    Request('flickr.favorites.getPublicList', args, callback);
  },


  //////////////////////////////////////////////////////////////////////////
  // Groups
  //////////////////////////////////////////////////////////////////////////

  /*! Get information about a group.

      Reference: http://www.flickr.com/services/api/flickr.groups.getInfo.html
      Authentication: none
      See also: http://www.flickr.com/services/feeds/

      Arguments:
        group_id (Required)
          The NSID of the group to fetch information for.
         lang (Optional)
          The language of the group name and description to fetch. If the language is not 
          found, the primary language of the group will be returned. Valid values are 
          the same as in feeds: de-de, en-us, es-us, fr-fr, it-it, ko-kr, pt-br, zh-hk.
  */
  groups_getInfo : function(callback, group_id, lang) {
    var args = {'group_id':group_id};
    if (Object.isString(lang)) {
      var rx = /^[a-z]{2}-[a-z]{2}$/;
      if (rx.test(lang))
      	args['lang'] = lang;
    }
    Request('flickr.groups.getInfo', args, callback);
  },


  /*! Search for groups.

      Reference: http://www.flickr.com/services/api/flickr.groups.search.html
      Authentication: none
      Notes: 18+ groups will only be returned for authenticated calls where the authenticated 
      user is over 18.

      Arguments:
        text (Required)
          The text to search for.
        per_page (Optional)
          Number of photos to return per page. If this argument is omitted, it defaults to 100. 
          The maximum allowed value is 500.
        page (Optional)
          The page of results to return. If this argument is omitted, it defaults to 1. 
  */
  groups_search : function(callback, text, per_page, page) {
    var args = {'text':text};
    if (Object.isNumber(per_page) && per_page > 0 && per_page <= 500)
      args['per_page'] = per_page;
    if (Object.isNumber(page) && page > 0)
      args['page'] = page;
    Request('flickr.groups.search', args, callback);
  },


  //////////////////////////////////////////////////////////////////////////
  // Interestingness
  //////////////////////////////////////////////////////////////////////////

  /*! Returns the list of interesting photos for the most recent day or a user-specified date.

      Reference: http://www.flickr.com/services/api/flickr.interestingness.getList.html
      Authentication: none

      Arguments:
        date (Optional)
          A specific date, formatted as YYYY-MM-DD, to return interesting photos for.
       extras (Optional)
          A comma-delimited list of extra information to fetch for each returned record. 
          Currently supported fields are: license, date_upload, date_taken, owner_name, icon_server, 
          original_format, last_update, geo, tags, machine_tags, o_dims, views, media.
        per_page (Optional)
          Number of photos to return per page. If this argument is omitted, it defaults to 100. 
          The maximum allowed value is 500.
        page (Optional)
          The page of results to return. If this argument is omitted, it defaults to 1. 
  */
  interestingness_getList : function(callback, date, extras, per_page, page) {
    var args = {};
    if (Object.isString(date)) {
      var rx = /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/;
      if (rx.test(date))
        args['date'] = date;
    }
    if (Object.isString(extras)) {
      args['extras'] = extras;
    }
    if (Object.isNumber(per_page) && per_page > 0 && per_page <= 500)
      args['per_page'] = per_page;
    if (Object.isNumber(page) && page > 0)
      args['page'] = page;
    Request('flickr.interestingness.getList', args, callback);
  },


  //////////////////////////////////////////////////////////////////////////
  // People
  //////////////////////////////////////////////////////////////////////////

  /*! Return a user's NSID, given their email address

      Reference: http://www.flickr.com/services/api/flickr.people.findByEmail.html
      Authentication: none

      Arguments:
        email (Required)
          The email address of the user to find (may be primary or secondary).
  */
  people_findByEmail : function(callback, email) {
    var args = {'find_email':email};
    Request('flickr.people.findByEmail', args, callback);
  },

  /*! Return a user's NSID, given their username.

      Reference: http://www.flickr.com/services/api/flickr.people.findByUsername.html
      Authentication: none

      Arguments:
        username (Required)
          The username of the user to lookup.
  */
  people_findByUsername: function(callback, username) {
    var args = {'username':username};
    Request('flickr.people.findByUsername', args, callback);
  },

  /*! Get information about a user.

      Reference: http://www.flickr.com/services/api/flickr.people.getInfo.html
      Authentication: none

      Arguments:
        user_id (Required)
          The NSID of the user to fetch information about.
  */
  people_getInfo: function(callback, user_id) {
    var args = {'user_id':user_id};
    Request('flickr.people.getInfo', args, callback);
  },

  /*! Returns the list of public groups a user is a member of.

      Reference: http://www.flickr.com/services/api/flickr.people.getPublicGroups.html
      Authentication: none

      Arguments:
        user_id (Required)
          The NSID of the user who's photos to return.
  */
  people_getPublicGroups: function(callback, user_id) {
    var args = {'user_id':user_id};
    Request('flickr.people.getPublicGroups', args, callback);
  },

  /*! Get a list of public photos for the given user.

      Reference: http://www.flickr.com/services/api/flickr.people.getPublicPhotos.html
      Authentication: none

      Arguments:
        user_id (Required)
          The NSID of the user who's groups to return.
        safe_search (Optional)
          Safe search setting:
            - 1 for safe.
            - 2 for moderate.
            - 3 for restricted.	
         (Please note: Un-authed calls can only see Safe content.)
        extras (Optional)
          A comma-delimited list of extra information to fetch for each returned record. 
          Currently supported fields are: license, date_upload, date_taken, owner_name, icon_server, 
          original_format, last_update, geo, tags, machine_tags, o_dims, views, media.
        per_page (Optional)
          Number of photos to return per page. If this argument is omitted, it defaults to 100. 
          The maximum allowed value is 500.
        page (Optional)
          The page of results to return. If this argument is omitted, it defaults to 1. 
  */
  people_getPublicPhotos: function(callback, user_id, safe_search, extras, per_page, page) {
    var args = {'user_id':user_id};
    if (Object.isNumber(safe_search) && (safe_search == 1 || safe_search == 2 || safe_search == 3))
    	args['safe_search'] = safe_search;
    if (Object.isString(extras)) {
      args['extras'] = extras;
    }
    if (Object.isNumber(per_page) && per_page > 0 && per_page <= 500)
      args['per_page'] = per_page;
    if (Object.isNumber(page) && page > 0)
      args['page'] = page;
    Request('flickr.people.getPublicPhotos', args, callback);
  },

  /*! Returns information for the calling user related to photo uploads.

      Reference: http://www.flickr.com/services/api/flickr.people.getUploadStatus.html
      Authentication: read
  */
  people_getUploadStatus: function(callback) {
    Request('flickr.people.getUploadStatus', {}, callback);
  },


  //////////////////////////////////////////////////////////////////////////
  // Photos
  //////////////////////////////////////////////////////////////////////////

   /*! Returns all visible sets and pools the photo belongs to.

      Reference: http://www.flickr.com/services/api/flickr.photos.getAllContexts.html
      Authentication: read

      Arguments:
        api_key (Required)
          Your API application key. See here for more details.
        photo_id (Required)
          The photo to return information for. 
  */
  photos_getAllContexts: function(callback, photo_id) {
    var args = {'photo_id':photo_id};
    Request('flickr.photos.getAllContexts', args, callback);
  },

  /*! Fetch a list of recent public photos from a users' contacts.

      Reference: http://www.flickr.com/services/api/flickr.photos.getContactsPublicPhotos.html
      Authentication: read

      Arguments:
        api_key (Required)
          Your API application key. See here for more details.
        user_id (Required)
          The NSID of the user to fetch photos for.
        count (Optional)
          Number of photos to return. Defaults to 10, maximum 50. This is only used if single_photo is not passed.
        just_friends (Optional)
          set as 1 to only show photos from friends and family (excluding regular contacts).
        single_photo (Optional)
          Only fetch one photo (the latest) per contact, instead of all photos in chronological order.
        include_self (Optional)
          Set to 1 to include photos from the user specified by user_id.
        extras (Optional)
          A comma-delimited list of extra information to fetch for each returned record. 
          Currently supported fields are: license, date_upload, date_taken, owner_name, icon_server, 
          original_format, last_update.
  */
  photos_getContactsPublicPhotos: function(callback, user_id, count, just_friends, single_photo, include_self, extras) {
    var args = {'user_id':user_id};
    if (Object.isNumber(count) && count > 0 && count <= 50)
      args['count'] = count;
    if (Object.isNumber(just_friends) && just_friends == 1)
      args['just_friends'] = just_friends;
    if (Object.isNumber(single_photo) && single_photo == 1)
      args['single_photo'] = single_photo;
    if (Object.isNumber(include_self) && include_self == 1)
      args['include_self'] = include_self;
    if (Object.isString(extras))
      args['extras'] = extras;
    Request('flickr.photos.getContactsPublicPhotos', args, callback);
  }

} // Protoflickr

Protoflickr.load();
